package com.lrkj.payfee.service.impl;

import com.lrkj.common.utils.LrkjDateUtil;
import com.lrkj.common.utils.NumberArithmeticUtils;
import com.lrkj.common.utils.uuid.IdUtils;
import com.lrkj.payfee.domain.ChargeNorm;
import com.lrkj.payfee.domain.RequirePay;
import com.lrkj.payfee.domain.RequireRecord;
import com.lrkj.payfee.mapper.RequirePayMapper;
import com.lrkj.payfee.service.IChargeNormService;
import com.lrkj.payfee.service.IRequirePayService;
import com.lrkj.payfee.service.IRequireRecordService;
import com.lrkj.payfee.vo.RequirePayVo;
import com.lrkj.payfee.vo.RoomArrearageItemVo;
import com.lrkj.payfee.vo.RoomArrearageVo;
import com.lrkj.property.domain.Room;
import com.lrkj.property.service.IRoomService;
import com.lrkj.waitress.domain.CustomInfo;
import com.lrkj.waitress.service.ICustomInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 催缴管理Service业务层处理
 *
 * @author yajun_ren
 * @date 2022-03-24
 */
@Service
public class RequirePayServiceImpl implements IRequirePayService {
    @Autowired
    private RequirePayMapper requirePayMapper;

    @Autowired
    private IRequireRecordService requireRecordService;

    @Autowired
    private IChargeNormService chargeNormService;

    @Autowired
    private IRoomService roomService;

    /**
     * 查询催缴管理
     *
     * @param id 催缴管理ID
     * @return 催缴管理
     */
    @Override
    public RequirePay selectRequirePayById(String id) {
        return requirePayMapper.selectRequirePayById(id);
    }

    /**
     * 查询催缴管理列表
     *
     * @param requirePay 催缴管理
     * @return 催缴管理
     */
    @Override
    public List<RequirePay> selectRequirePayList(RequirePay requirePay) {
        return requirePayMapper.selectRequirePayList(requirePay);
    }

    /**
     * 新增催缴管理
     *
     * @param requirePay 催缴管理
     * @return 结果
     */
    @Override
    public int insertRequirePay(RequirePay requirePay) {
        requirePay.setId(IdUtils.simpleUUID());
        this.createDetail(requirePay);
        return requirePayMapper.insertRequirePay(requirePay);
    }

    /**
     * 修改催缴管理
     *
     * @param requirePay 催缴管理
     * @return 结果
     */
    @Override
    public int updateRequirePay(RequirePay requirePay) {
        return requirePayMapper.updateRequirePay(requirePay);
    }

    /**
     * 批量删除催缴管理
     *
     * @param ids 需要删除的催缴管理ID
     * @return 结果
     */
    @Override
    public int deleteRequirePayByIds(String[] ids) {
        return requirePayMapper.deleteRequirePayByIds(ids);
    }

    /**
     * 删除催缴管理信息
     *
     * @param id 催缴管理ID
     * @return 结果
     */
    @Override
    public int deleteRequirePayById(String id) {
        return requirePayMapper.deleteRequirePayById(id);
    }

    @Override
    public List<RequirePay> requireBillRommCensus(RequirePayVo requirePayVo) {
        return requirePayMapper.requireBillRommCensus(requirePayVo);
    }

    @Override
    public List<Map<String, Object>> roomArrearageList(RoomArrearageVo roomArrearageVo) {
        List<Map<String, Object>> listMap = new ArrayList<>();
        List<RoomArrearageVo> roomArrearageVos = requirePayMapper.roomArrearageList(roomArrearageVo);
        if (null != roomArrearageVos && roomArrearageVos.size() > 0) {
            Map<String, AtomicReference<BigDecimal>> chargeItemMap = new HashMap<>();
            ChargeNorm eg = new ChargeNorm();
            eg.setDeptId(roomArrearageVo.getCommunityId());
            List<ChargeNorm> chargeNorms = chargeNormService.selectChargeNormList(eg);
            chargeNorms.stream().forEach(x -> {
                chargeItemMap.put(x.getChargeId(), new AtomicReference<>(new BigDecimal(0)));
            });

            roomArrearageVos.stream().forEach(x -> {
                Map<String, Object> bean = new HashMap<>();
                List<RoomArrearageItemVo> itemList = x.getRoomArrearageItemVos();
                if (null != itemList && itemList.size() > 0) {
                    //升序
                    Collections.sort(itemList, new Comparator<RoomArrearageItemVo>() {
                        @Override
                        public int compare(RoomArrearageItemVo o1, RoomArrearageItemVo o2) {
                            return o1.getFinishTime().compareTo(o2.getFinishTime());
                        }
                    });
                    RoomArrearageItemVo firstItem = itemList.get(0);
                    RoomArrearageItemVo lastItem = itemList.get(itemList.size() - 1);
                    //欠费月数
                    Integer difMonth = LrkjDateUtil.getDifMonth(firstItem.getBeginTime(), lastItem.getFinishTime());
                    //彺月欠费金额
                    BigDecimal wyAmountOwed = this.wyOwedMonthMoney(itemList);
                    //本月欠费金额
                    BigDecimal byAmountOwed = this.byOwedMonthMoney(itemList);
                    for (String key : chargeItemMap.keySet()) {
                        AtomicReference<BigDecimal> money = new AtomicReference<>(new BigDecimal(0));
                        itemList.stream().forEach(item -> {
                            if (item.getChargeId().equals(key)) {
                                money.set(NumberArithmeticUtils.safeAdd(money.get(), item.getAmountOwed()));
                            }
                        });
                        bean.put(key, money);
                    }
                    bean.put("roomId", x.getRoomId());
                    bean.put("roomName", x.getRoomName());
                    bean.put("customName", x.getCustomName());
                    bean.put("difMonth",difMonth+1);
                    bean.put("wyAmountOwed",wyAmountOwed);
                    bean.put("byAmountOwed",byAmountOwed);
                    bean.put("sumAmout",NumberArithmeticUtils.safeAdd(byAmountOwed, wyAmountOwed));
                    listMap.add(bean);
                }
            });
        }
        return listMap;
    }

    //获取彺月欠费金额
    private BigDecimal wyOwedMonthMoney(List<RoomArrearageItemVo> itemList) {
        //彺月欠费列表
        List<RoomArrearageItemVo> wyItemList = itemList.stream().filter(x -> {
            String years = LrkjDateUtil.getFormatTimeString(x.getBeginTime(), "yyyy-MM");
            String beforeYears = LrkjDateUtil.getFormatTimeString(new Date(), "yyyy-MM");
            return !years.equals(beforeYears);
        }).collect(Collectors.toList());

        AtomicReference<BigDecimal> amountOwed = new AtomicReference<>(new BigDecimal(0));
        wyItemList.stream().forEach(x -> {
            amountOwed.set(NumberArithmeticUtils.safeAdd(amountOwed.get(), x.getAmountOwed()));
        });
        return amountOwed.get();
    }

    //获取本月欠费金额
    private BigDecimal byOwedMonthMoney(List<RoomArrearageItemVo> itemList) {
        //彺月欠费列表
        List<RoomArrearageItemVo> wyItemList = itemList.stream().filter(x -> {
            String years = LrkjDateUtil.getFormatTimeString(x.getBeginTime(), "yyyy-MM");
            String beforeYears = LrkjDateUtil.getFormatTimeString(new Date(), "yyyy-MM");
            return years.equals(beforeYears);
        }).collect(Collectors.toList());

        AtomicReference<BigDecimal> amountOwed = new AtomicReference<>(new BigDecimal(0));
        wyItemList.stream().forEach(x -> {
            amountOwed.set(NumberArithmeticUtils.safeAdd(amountOwed.get(), x.getAmountOwed()));
        });
        return amountOwed.get();
    }


    /**
     * 批量新增催缴管理信息
     *
     * @param requirePays 催缴管理对象
     */
    public int batchAddData(List<RequirePay> requirePays) {
        return requirePayMapper.batchAddData(requirePays);
    }


    private void createDetail(RequirePay requirePay) {
        if (requirePay.getRequireRecordList() != null) {
            List<RequireRecord> recordList = new ArrayList<>();
            requirePay.getRequireRecordList().stream().forEach(x -> {
                RequireRecord record = new RequireRecord();
                Room room = roomService.selectRoomById(x.getRoomId());
                record.setId(IdUtils.simpleUUID());
                record.setRequireId(requirePay.getId());
                record.setCustomId(room.getOwnerId());
                record.setRoomId(x.getRoomId());
                record.setRequireContent(requirePay.getRequireContent());
                record.setRequireTime(requirePay.getRequireTime());
                record.setStatus("10");
                recordList.add(record);
            });
            requireRecordService.doSaveList(recordList);
        }
    }

}
